package com.leezai.mqtt.Parser;

import com.alibaba.fastjson2.JSONObject;
import com.leezai.mqtt.dto.HexDto;

import java.nio.charset.StandardCharsets;
import java.util.List;

public class ByteStreamParser implements ByteParser{

    /**
     * 将字节数组按规则解析为JSON Map
     *
     * @param bytes 字节数组
     * @param rules 解析规则列表
     * @return 解析后的键值对Map
     */
    public JSONObject parseBytes(byte[] bytes, List<HexDto> rules) {
        JSONObject result = new JSONObject();

        for (HexDto rule : rules) {
            try {
                Object value = extractValue(bytes, rule);
                result.put(rule.getName(), value);
            } catch (Exception e) {
                // 记录错误但继续处理其他字段
                result.put(rule.getName(), "解析错误: " + e.getMessage());
            }
        }
        return result;
    }

    /**
     * 根据规则从字节数组中提取值
     *
     * @param data 字节数组
     * @param rule 解析规则
     * @return 提取的值
     */
    private Object extractValue(byte[] data, HexDto rule) {
        int startByte = rule.getStartPosition();
        int byteLength = rule.getLength();

        // 根据字节长度提取数据
        switch (rule.getType()) {
            case "1": // 字符串
                return extractString(data, startByte, byteLength);
            case "2": // 整数
                long intValue = extractLong(data, startByte, byteLength);
                if (rule.getScale() != null) {
                    return (double) intValue / rule.getScale();
                } else {
                    return intValue;
                }
            case "3": // 浮点数
                double doubleValue = extractDouble(data, startByte, byteLength);
                if (rule.getScale() != null) {
                    return (float) doubleValue / rule.getScale();
                } else {
                    return doubleValue;
                }
            case "4": // 十六进制
                return extractHex(data, startByte, byteLength);
            default:
                return null;
        }
    }

    private String extractString(byte[] data, int startByte, int byteLength) {
        if (startByte >= data.length) {
            return "";
        }

        int actualLength = Math.min(byteLength, data.length - startByte);
        byte[] stringBytes = new byte[actualLength];
        System.arraycopy(data, startByte, stringBytes, 0, actualLength);
        return new String(stringBytes, StandardCharsets.UTF_8).trim();
    }

    private long extractLong(byte[] data, int startByte, int byteLength) {
        if (startByte >= data.length) {
            return 0;
        }

        int actualLength = Math.min(byteLength, data.length - startByte);

        switch (actualLength) {
            case 1:
                // 8位有符号整数
                return data[startByte];
            case 2:
                // 16位有符号整数（大端序）
                return (short) ((data[startByte] << 8) | (data[startByte + 1] & 0xFF));
            case 4:
                // 32位有符号整数（大端序）
                return (data[startByte] << 24) |
                        ((data[startByte + 1] & 0xFF) << 16) |
                        ((data[startByte + 2] & 0xFF) << 8) |
                        (data[startByte + 3] & 0xFF);
            case 8:
                // 64位有符号长整数（大端序）
                return ((long)data[startByte] << 56) |
                        ((long)(data[startByte + 1] & 0xFF) << 48) |
                        ((long)(data[startByte + 2] & 0xFF) << 40) |
                        ((long)(data[startByte + 3] & 0xFF) << 32) |
                        ((long)(data[startByte + 4] & 0xFF) << 24) |
                        ((long)(data[startByte + 5] & 0xFF) << 16) |
                        ((long)(data[startByte + 6] & 0xFF) << 8) |
                        ((long)(data[startByte + 7] & 0xFF));
            default:
                throw new RuntimeException("无效的字节长度" + actualLength + "，整数字节长度 支持 1字节 2字节 4字节 8字节");
        }
    }

    private String extractHex(byte[] data, int startByte, int byteLength) {
        if (startByte >= data.length) {
            return "";
        }

        int actualLength = Math.min(byteLength, data.length - startByte);
        StringBuilder hex = new StringBuilder();
        for (int i = 0; i < actualLength; i++) {
            hex.append(String.format("%02X", data[startByte + i]));
        }
        return hex.toString();
    }

    private double extractDouble(byte[] data, int startByte, int byteLength) {
        if (startByte >= data.length) {
            return 0.0;
        }

        int actualLength = Math.min(byteLength, data.length - startByte);

        // 根据字节长度选择合适的解析方式
        switch (actualLength) {
            case 4:
                // 32位浮点数（float）
                int intBits = (data[startByte] & 0xFF) << 24 |
                        (data[startByte + 1] & 0xFF) << 16 |
                        (data[startByte + 2] & 0xFF) << 8 |
                        (data[startByte + 3] & 0xFF);
                return (double) Float.intBitsToFloat(intBits);

            case 8:
                // 64位浮点数（double）
                long longBits = (long) (data[startByte] & 0xFF) << 56 |
                        (long) (data[startByte + 1] & 0xFF) << 48 |
                        (long) (data[startByte + 2] & 0xFF) << 40 |
                        (long) (data[startByte + 3] & 0xFF) << 32 |
                        (long) (data[startByte + 4] & 0xFF) << 24 |
                        (long) (data[startByte + 5] & 0xFF) << 16 |
                        (long) (data[startByte + 6] & 0xFF) << 8 |
                        (long) (data[startByte + 7] & 0xFF);
                return Double.longBitsToDouble(longBits);

            default:
                // 对于其他长度，解析为整数然后转换为double
                throw new RuntimeException("无效的字节长度" + actualLength + "，浮点数字节长度 支持 4字节 8字节");
        }
    }
}
